# from gevent import monkey
# monkey.patch_all()
import os
import random
import re
import sys
import telnetlib
import time
import traceback
from datetime import datetime
from dateutil.relativedelta import relativedelta
from django.db import close_old_connections
from django.db.models import Q
from models.models import OltInfo, BoardInfo, SnBlacklist, CheckSnMac, CheckTotalOltUser, OntRecord
from omp.models import OmpDevice, OnuAutoFindInfo
from AutoRegister.settings import LOG_DIR, FILTER_OLT_IP
from tools.redis import redisPool
from tools.tools import write_log, Save_OntRecord
from tools.Robot import sendTeam

# 初始化redis连接
redis_oper = redisPool()


class telnetip(object):
    def __init__(self, tnip, tnport, username, password, user_timestamp=None):
        close_old_connections()
        self.tn = telnetlib.Telnet()
        self.tnip = tnip
        # self.tnip = "10.10.10.201"
        self.tnport = int(tnport)
        self.username = username
        self.password = password
        self.user_timestamp = user_timestamp
        self.onu_set = set()
        try:
            self.olt_id = OltInfo.objects.get(olt_ip=self.tnip, olt_port=self.tnport).olt_id
            self.oltObj = OltInfo.objects.get(olt_ip=self.tnip, olt_port=self.tnport)
        except Exception as e:
            print("获取self.olt_id 报错：%s" % str(e))
            self.olt_id = 0
        print("%s:%s self.olt_id: %s" % (self.tnip, self.tnport, self.olt_id))
        # self.olt_id = 1

    def login_host(self, userrole=None, time_out=None):
        close_old_connections()
        """
        return  timeout 连接超时
                userrole  user 用户登录  or  is None 系统登录
        """
        if time_out is None:
            time_out = 5

        # 用户启动OLT
        if userrole == "user":
            up_down_remind = "false"
            try:
                self.tn.open(self.tnip, self.tnport, timeout=time_out)
            except Exception as e:
                print('e==>', e)
                return False, "无法连接 %s:%s" % (self.tnip, self.tnport)

        # 正常启动OLT
        else:
            if self.olt_id == 0:
                print("发送微信，IP和端口不存在，无法登陆OLT")
                msg = "找不到 %s:%s OLT相关数据,无法登陆" % (self.tnip, self.tnport)
                # 发送微信 不携带wechat_group参数 默认发送到 CASE_GROUP_NAME
                sendTeam(msg, 'robot')
                # 运行日志 和 错误日志 # data, ip, port, level=None
                write_log(msg, self.tnip, self.tnport, userrole, 'error')
                # userrole=userrole,
                return False, msg
            # 连接Telnet服务器
            print("connecting to {}:{}".format(self.tnip, self.tnport))
            up_down_remind = True if self.oltObj.up_down_remind == "True" else False
            print("up_down_remind", up_down_remind)
            while True:
                try:
                    self.tn.open(self.tnip, self.tnport, timeout=time_out)
                except Exception as e:
                    # 网络不通，发送信息
                    print("发送微信,无法连接%s:%s OLT : %s" % (self.tnip, self.tnport, e))
                    msg = "[{}]登陆异常\n负责人请注意\n- IP:{}\n- 时间:{}\n登陆失败！！！".format(self.oltObj.olt_name, self.tnip,
                                                                               str(datetime.now())[:19])
                    if up_down_remind:
                        # 意外退出，是否发送信息的标记
                        sendmsg_swich = redis_oper.conn.get("%s_%s_sendmsg_swich" % (self.tnip, self.tnport))
                        if sendmsg_swich is None:
                            # 发送微信
                            # sendTeam(msg, 'robot')
                            pass

                    # 添加已经发送掉线信息的信号
                    redis_oper.conn.set("%s_%s_sendmsg_swich" % (self.tnip, self.tnport), "send")
                    # 运行日志 和 错误日志 data, ip, port, level=None
                    write_log(traceback.format_exc(), self.tnip, self.tnport, level="error")
                    runstate = redis_oper.redis_get("%s_%s_runstate" % (self.tnip, self.tnport))
                    if runstate == "false":
                        return False, "OLT处于连接失败状态，用户执行退出"
                    # 代表OLT已经启动 ，但是 是否启动成功 不一定
                    redis_oper.conn.set("%s_%s_runstate" % (self.tnip, self.tnport), "true")

                    # 人为操作  启动运行OLT失败 返回字段
                    redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                    time.sleep(1)
                    continue
                else:
                    break

        try:
            result1 = self.tn.read_until(b'>>User name:', timeout=10)
        except Exception as e:
            if "Connection reset by peer" in str(e):
                return False, "Connection reset by peer"

        self.tn.write(self.username.encode('ascii') + b'\n')
        # 等待Password出现后输入用户名，最多等待10秒
        result2 = self.tn.read_until(b'>>User password:', timeout=10)
        self.tn.write(self.password.encode('ascii') + b'\n')
        if self.tnip in FILTER_OLT_IP:
            time.sleep(45)
        else:
            time.sleep(random.randint(1, 3))

        self.command_result = self.tn.read_very_eager().decode('ascii', errors='ignore')
        if self.command_result:
            if "Username or password invalid" in self.command_result:
                print("用户名或密码无效 %s" % self.command_result)
                # 运行日志
                write_log(data=self.command_result, ip=self.tnip, port=self.tnport, userrole=userrole)
                # 人为操作  启动运行OLT失败 返回字段
                redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                return False, "用户名或密码无效"
            elif 'error' in self.command_result:
                print("登录出现错误 -> %s" % self.command_result)
                write_log(data=self.command_result, ip=self.tnip, port=self.tnport, level="error",
                          userrole=userrole)
                # 人为操作  启动运行OLT失败 返回字段
                redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                return False, self.command_result
            elif 'Reenter times have reached the upper limit' in self.command_result:
                print("超出最大同时登录限制 -> %s" % self.command_result)
                # 人为操作  启动运行OLT失败 返回字段
                write_log(data=self.command_result, ip=self.tnip, port=self.tnport, userrole=userrole)
                redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                return False, "超出最大同时登录限制"

            elif ">" in self.command_result:
                msg = "发送消息状态为：false"
                # 登录成功 ，发送信息
                if up_down_remind:
                    # 正常登陆 还是 因为异常断开，重新登陆
                    redis_key = "%s_exception_connect" % self.olt_id
                    exception_connect = redis_oper.redis_get(redis_key)
                    # 正常登陆
                    olt_name = self.oltObj.olt_name
                    if exception_connect is None:
                        pass
                    # 上次断开连接了，重新恢复连接
                    else:
                        msg = "【%s】连接已恢复 \n- 时间:%s\n- IP:%s\n登陆已成功！" % (olt_name, str(datetime.now())[:19], self.tnip)
                        self.oltObj.host_status = "正常"
                        self.oltObj.save()
                        redis_oper.redis_del(redis_key)
                        sendTeam(msg, 'robot')

                # 删除上次意外断开 发送过信息的记号字段
                redis_oper.conn.delete("%s_%s_sendmsg_swich" % (self.tnip, self.tnport))
                write_log(data=msg, ip=self.tnip, port=self.tnport, userrole=userrole)
                print("登录到OLT")
                return True, "登录成功"
            else:
                print("未知情况登陆失败：-> %s" % (str(self.command_result)))
                write_log(data=self.command_result, ip=self.tnip, port=self.tnport, level="error")
                # 人为操作  启动运行OLT失败 返回字段
                redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
                return False, self.command_result
        else:
            print("登录失败")

            write_log(data=self.command_result, ip=self.tnip, port=self.tnport, level="error")
            # 人为操作  启动运行OLT失败 返回字段
            redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), "fail", 10)
            return False, self.command_result

    # 基本配置
    def base_config(self, autosave, userrole=None):
        close_old_connections()

        command1 = "\nenable\nconfig"
        command3 = "switch language-mode"
        self.commandResult_fun(command=command1, userrole=userrole)
        # self.commandResult_fun(command=command2)
        self.commandResult_fun(command=command3, userrole=userrole)
        command4 = "idle-timeout 30"
        self.commandResult_fun(command=command4, userrole=userrole)

        command = "scroll\n"
        self.result = self.commandResult_fun(command=command, read_mode=3, userrole=userrole)

        """ 命令：
             scroll      
                 系统正在批量备份、数据平滑或配置恢复，此时不对命令产生响应  """

        print("self.result---->", self.result)

        # 连接异常
        if self.result is None:
            return

        while True:
            if "系统正忙" in self.result or "Failure: System is busy, please retry after a while" in self.result:
                command = "scroll\n"
                self.result = self.commandResult_fun(command=command, userrole=userrole)
                time.sleep(5)
            # elif "系统正在批量备份、数据平滑或配置恢复，此时不对命令产生响应" in self.result:
            elif "此时不对命令产生响应" in self.result:
                command = "scroll\n"
                self.result = self.commandResult_fun(command=command, userrole=userrole)
                time.sleep(5)
            elif "Command:" in self.result:
                command3 = "switch language-mode"
                self.commandResult_fun(command=command3, userrole=userrole)
            else:
                break
        if autosave:
            try:
                olt_obj = OltInfo.objects.get(olt_id=self.olt_id)
                # 保存方式为自动保存
                if olt_obj.save_mode == "autosave":
                    save_command1 = "autosave interval %s" % (int(olt_obj.save_hours) * 60)
                    self.commandResult_fun(command=save_command1, userrole=userrole)
                    save_command2 = "autosave interval on"
                    self.commandResult_fun(command=save_command2, userrole=userrole)
                elif olt_obj.save_mode == "activesave":
                    save_command3 = "autosave interval off"
                    self.commandResult_fun(command=save_command3, userrole=userrole)
            except OltInfo.DoesNotExist:
                pass

        # is None 表示 系统启动 注册ONT 使用的 telnetobj。
        if userrole is None:
            # 人为操作  启动运行OLT成功 反馈字段
            redis_oper.conn.set("%s_%s_startrun_signal" % (self.tnip, self.tnport), 1, 10)
            redis_oper.conn.set("%s_%s_running" % (self.tnip, self.tnport), self.olt_id, 10)

        return True

    def onu_login(self):
        close_old_connections()
        while True:

            # 保存数据方式 分为主动保存和自动保存
            self.oltObj.host_status = '正常'
            self.oltObj.save()
            # save_mode = "activesave"
            if self.oltObj.save_mode == "activesave":
                save_time = redis_oper.redis_get("%s_save_time" % self.olt_id)
                if save_time is None:
                    save_time = datetime.now() - relativedelta(minutes=1)
                    redis_oper.conn.set("%s_save_time" % self.olt_id, str(save_time)[:19])
                if isinstance(save_time, str):
                    save_time = datetime.strptime(save_time, "%Y-%m-%d %H:%M:%S")
                if datetime.now() > save_time:
                    self.tn.write("save".encode('ascii') + b'\n' + b'\n')
                    save_hours = self.oltObj.save_hours
                    while True:
                        time.sleep(3)
                        self.result = self.tn.read_very_eager().decode('GBK', errors='ignore')
                        echo_resutl = redis_oper.redis_get("%s_%s_echo" % (self.tnip, self.tnport))
                        if echo_resutl == "true":
                            redis_oper.conn.lpush("%s_%s_echo_result" % (self.tnip, self.tnport), self.result)
                            redis_oper.conn.lpush("%s_%s_echo_result" % (self.tnip, self.tnport),
                                                  str(datetime.now())[:19])

                        redis_oper.conn.set("%s_%s_running" % (self.tnip, self.tnport), self.olt_id, 10)
                        write_log(data=self.result, ip=self.tnip, port=self.tnport)
                        time.sleep(2)
                        # 连接异常
                        if self.result is None:
                            return "exception"

                        # 查询mysql中保存olt的时间间隔
                        if "数据保存完成" in self.result:
                            save_time += relativedelta(hours=save_hours)
                            redis_oper.conn.set("%s_save_time" % self.olt_id,
                                                datetime.strftime(save_time, "%Y-%m-%d %H:%M:%S"))
                            break
                        elif "数据保存完全" in self.result:
                            save_time += relativedelta(hours=save_hours)
                            redis_oper.conn.set("%s_save_time" % self.olt_id,
                                                datetime.strftime(save_time, "%Y-%m-%d %H:%M:%S"))
                            break
                        elif "系统正在加载" in self.result or "系统正忙" in self.result:
                            save_time += relativedelta(hours=save_hours)
                            redis_oper.conn.set("%s_save_time" % self.olt_id,
                                                datetime.strftime(save_time, "%Y-%m-%d %H:%M:%S"))
                            break
                        elif "失败：系统正忙，请稍后再试" in self.result:
                            continue

                        elif "错误位于'^'所指的位置" in self.result:
                            print("SAVE command error-parameter", self.result)
                            write_log(data=self.result, ip=self.tnip, port=self.tnport, level="error")

            # 保存OLT配置信息
            save_configuration = redis_oper.redis_get("%s_save_configuration" % self.olt_id)
            if save_configuration:
                config_result = self.olt_configinfo()
                if config_result:
                    file_path = os.path.join(LOG_DIR, "%s_%s" % (self.tnip, self.tnport))
                    if not os.path.exists(file_path):
                        os.makedirs(file_path, mode=0o777, exist_ok=True)

                    filename = os.path.join(file_path, "%s_%s_config.txt" % (self.tnip, self.tnport))
                    with open(filename, "w") as f:
                        f.write("%s 配置信息" % self.oltObj.olt_name)
                        f.write("\n")
                        for i in config_result.splitlines()[5:-2]:
                            f.write(i)
                            f.write("\n")

                redis_oper.redis_del("%s_save_configuration" % self.olt_id)

            if self.onu_set:
                # 运行日志
                msg = "%s:%s 中 集合：%s " % (self.tnip, self.tnport, self.onu_set)
                print(msg)
                #
                write_log(data=msg, ip=self.tnip, port=self.tnport)
                onu_sn_redis = list(self.onu_set)
                if onu_sn_redis:
                    onu_sn_redis = onu_sn_redis[0]
                else:
                    onu_sn_redis = ""
                print("集合取出计费要求注册的ONT信息：", onu_sn_redis)
            else:
                # 取出
                onu_sn_redis = redis_oper.conn.rpop("%s_%s_billing_onu" % (self.tnip, self.tnport))
                if onu_sn_redis:
                    onu_sn_redis = onu_sn_redis.decode()
                print("redis取出计费要求注册的ONT信息：", onu_sn_redis)
            print("onu_set集合 ", self.onu_set)
            # 注册GPON光猫-发现光猫
            command = "display ont autofind all"
            self.commandResult_fun(command=command)
            # print("发现光猫命令(display ont autofind all)...", self.result)

            if self.result == "logout":
                # 计费发起的注册ONT
                if onu_sn_redis:
                    # 计费触发注册ONU标识删除
                    self.onu_set.discard(onu_sn_redis)
                    redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                        "failed-logout", 10)
                return "logout"

            if self.result is None:
                # 计费发起的注册ONT
                if onu_sn_redis:
                    # 计费触发注册ONU标识删除
                    self.onu_set.discard(onu_sn_redis)
                    redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                        "failed-result is None", 10)  # id + sn码
                return "exception"
            else:
                keyword_str = ["槽位主控板的数据保存", "请稍候", "数据正在保存", "配置文件"]

                go_back = False

                for i in keyword_str:
                    if self.result and i in self.result:
                        print("%s wait.." % i)
                        go_back = True

                        # 记录计费主动注册的ONT
                        if onu_sn_redis:
                            if onu_sn_redis not in self.onu_set:
                                self.onu_set.add(onu_sn_redis)
                        break
                if go_back:
                    time.sleep(1)
                    continue

                time_start = time.time()
                if "失败: 不存在自动发现的ONT" in self.result:
                    print(f" {self.oltObj.olt_name} 不存在自动发现的光猫({str(datetime.now())[:19]})")
                    if onu_sn_redis:
                        if onu_sn_redis not in self.onu_set:
                            self.onu_set.add(onu_sn_redis)
                        else:
                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis), "not found onu", 10)  # id + sn码
                            self.onu_set.discard(onu_sn_redis)

                    # 检查是否有 ONT批量迁移 字段，并且ONT已经全部注册完毕
                    batchmigrate = redis_oper.redis_get("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
                    if batchmigrate:
                        redis_oper.redis_del("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))

                    time.sleep(1)
                    continue
                elif "自动发现ONT个数为" in self.result:
                    # 获取GPON ONU信息
                    re_result_gpon = re.findall("框/槽/端口 .*?: (.*?)\r\n.*?ONT SN .*?: (.*?)\r\n", self.result)
                    print("发现GPON光猫...过滤后的有用信息", re_result_gpon)
                    # 获取EPON ONU信息
                    if self.result.find('ONT类型') != -1:
                        re_result_epon = re.findall("框/槽/端口.*?: (.*?)\r\n.*\r\n.*ONT MAC.*: (.*?)\r\n", self.result)

                    elif self.result.find('ONT网络侧接口类型') != -1:
                        re_result_epon = re.findall("框/槽/端口.*?: (.*?)\n.*\n.*ONT MAC.*: (.*?)\n", self.result)
                    else:
                        re_result_epon = re.findall("框/槽/端口.*?: (.*?)\n.*ONT MAC.*: (.*?)\n", self.result)
                    print("发现EPON光猫...过滤后的有用信息", re_result_epon)
                    re_result = re_result_gpon + re_result_epon
                    # 计费触发的注册ONU
                    if onu_sn_redis:
                        logmsg = "发现半自动注册ONT -- 开始 SN:%s" % onu_sn_redis
                        write_log(logmsg, self.tnip, self.tnport)
                        if "-" in onu_sn_redis[:16]:
                            onu_sn_redis = onu_sn_redis[:14]
                        else:
                            onu_sn_redis = onu_sn_redis[:16]
                        frameid = ""
                        slotid = ""
                        board_port = ""
                        onu_sn = onu_sn_redis
                        for i in re_result:
                            i_list = list(i)
                            if "-" in str(i_list[1][:16]):
                                find_sn = str(i_list[1][:14])
                            else:
                                find_sn = str(i_list[1][:16])

                            if find_sn == str(onu_sn_redis):
                                location_list = i_list[0].split("/")
                                frameid = str(location_list[0])  # 框
                                slotid = str(location_list[1])  # 槽
                                board_port = str(location_list[2])  # 板口
                                break

                        # 计费发起注册ONU 2次发现机会。2次还没有发现，结束注册流程
                        if not all([frameid, slotid, board_port]):
                            if onu_sn_redis:
                                if onu_sn_redis not in self.onu_set:
                                    self.onu_set.add(onu_sn_redis)
                                    time.sleep(4)
                                    logmsg = "发现半自动注册ONT -- 没发现要注册的ONT第一次 SN:%s" % onu_sn_redis
                                    write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                else:
                                    redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis), "not found onu",
                                                        10)  # id + sn码
                                    self.onu_set.discard(onu_sn_redis)

                                    logmsg = "%s\n手动注册ONT失败 --\n未找到ONT:%s\n退出注册流程，共搜索两次" % (
                                        self.oltObj.olt_name, onu_sn_redis)
                                    write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                    sendTeam(logmsg, 'robot')
                            continue
                    # 正常自动注册ONT
                    else:
                        logmsg = "正常流程注册ONT,过滤无需自动注册的ONT--开始"
                        print(logmsg)
                        # 运行日志
                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                        # 计费发起的ONT批量迁移数据  除了端口过滤以外的所有光猫全部注册
                        # batchmigrate = redis_oper.redis_get("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
                        re_result = self.filter_foreign_onu(re_result)
                        if re_result.__len__() == 0:
                            continue
                        frameid, slotid, board_port, onu_sn = self.filter_onu(olt_id=self.olt_id,
                                                                              onu_info_list=re_result,
                                                                              batchmigrate=None)

                        logmsg = "正常流程注册ONT,过滤无需自动注册的ONT--结束 (frameid:%s slotid:%s board_port:%s SN:%s)" % (
                            frameid, slotid, board_port, onu_sn)
                        write_log(logmsg, self.tnip, self.tnport)
                        # if not all([frameid, slotid, board_port]):
                        #     logmsg = "%s:%s -- No registration is available ONU" % (self.tnip, self.tnport)
                        #     print(logmsg)
                        #
                        #     # 检查是否有 ONT批量迁移 字段，并且除了端口设置为过滤的ONT已经全部注册完毕
                        #     batchmigrate = redis_oper.redis_get("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
                        #     if batchmigrate:
                        #         redis_oper.redis_del("%s_%s_ONTbatchmigrate" % (self.tnip, self.tnport))
                        #
                        #     time.sleep(2)
                        #     continue
                    find_time = str(datetime.now())[:19]
                    try:
                        board_info_obj = BoardInfo.objects.get(olt_info_id=self.olt_id, slotid=slotid,
                                                               board_port=board_port)
                    except BoardInfo.DoesNotExist:
                        board_info_obj = BoardInfo.objects.get(olt_info_id=self.olt_id, default_data="Y")
                        print("异步任务，缺少板卡信息，使用默认数据注册ONU")
                        # OLT名称、板卡位置
                        logmsg = "OLT:%s,位置:0框%s槽%s口，无板卡数据,使用默认数据注册ONT SN:%s" % (
                            self.oltObj.olt_name, slotid, board_port, onu_sn)
                        print(logmsg)
                        # 运行日志 和 错误日志
                        write_log(data=logmsg, ip=self.tnip, port=self.tnport, level="error")
                        # 发送微信  异步任务
                    olt_name = self.oltObj.olt_name
                    if len(onu_sn) == 16:
                        line_template = board_info_obj.line_template_gpon  # GPON线路模板
                        business_template = board_info_obj.business_template_gpon  # GPON业务模板
                        business_intimal = board_info_obj.business_intimal  # 业务内层
                        business_outer = board_info_obj.business_outer  # 业务外层
                        gemport = str(board_info_obj.gemport)
                    elif len(onu_sn) == 14:
                        line_template = board_info_obj.line_template_epon  # EPON线路模板
                        business_template = board_info_obj.business_template_epon  # EPON业务模板
                        business_intimal = board_info_obj.business_intimal  # 业务内层
                        business_outer = board_info_obj.business_outer  # 业务外层
                        gemport = str(board_info_obj.gemport)
                    else:
                        line_template = None
                        business_template = None
                        business_intimal = None
                        business_outer = None
                        gemport = None

                    if not all([str(frameid), str(slotid), str(board_port), onu_sn, find_time, str(line_template),
                                str(business_template), str(business_intimal), str(business_outer), str(gemport)]):
                        msg = "缺少注册ONT必要参数：\n框：%s\n槽：%s\n口：%s\nSN：%s\n发现时间：%s\n" \
                              "线路模板：%s\n业务模板：%s\n业务内层：%s\n业务外层：%s\ngemport：%s\n" % (
                                  frameid,
                                  slotid,
                                  board_port,
                                  onu_sn,
                                  find_time,
                                  line_template,
                                  business_template,
                                  business_intimal,
                                  business_outer,
                                  gemport,
                              )

                        write_log(data=msg, ip=self.tnip, port=self.tnport, level="error")
                        # 计费发起的注册ONT
                        if onu_sn_redis:
                            # 计费触发注册ONU标识删除
                            self.onu_set.discard(onu_sn_redis)
                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                "failed-lack necessary parameters", 10)  # id + sn码

                        time.sleep(1)
                        continue
                    else:
                        full_msg = "注册所需参数\n框：%s\n槽：%s\n口：%s\nSN：%s\n发现时间：%s\n线路模板：%s" \
                                   "\n业务模板：%s\n业务内层：%s\n业务外层：%s\ngemport：%s\n" % (
                                       frameid,
                                       slotid,
                                       board_port,
                                       onu_sn,
                                       find_time,
                                       line_template,
                                       business_template,
                                       business_intimal,
                                       business_outer,
                                       gemport,
                                   )

                        # 运行日志
                        write_log(data=full_msg, ip=self.tnip, port=self.tnport)

                    # GPON 注册
                    if len(onu_sn) == 16:
                        logmsg = "进入GPON注册流程 开始"
                        print(logmsg)
                        # 运行日志
                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                        gponlogin_finish, flow_result = self.gpon_flow(frameid=frameid,
                                                                       slotid=slotid,
                                                                       board_port=board_port,
                                                                       onu_sn=onu_sn,
                                                                       find_time=find_time,
                                                                       line_template_GPON=line_template,
                                                                       business_template_GPON=business_template,
                                                                       business_intimal=business_intimal,
                                                                       business_outer=business_outer,
                                                                       gemport=gemport)
                        logmsg = "进入GPON注册流程 结束"
                        print(logmsg)
                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                        if not gponlogin_finish:
                            if flow_result == "正在保存数据":
                                time.sleep(2)
                            # 用户执行退出
                            elif flow_result == "logout":
                                # 计费发起的注册ONT
                                if onu_sn_redis:
                                    # 计费触发注册ONU标识删除
                                    self.onu_set.discard(onu_sn_redis)
                                    redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                        "failed-logout", 10)
                                break

                            elif flow_result == "失败: 序列码已经存在":
                                # 运行日志
                                logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  开始" % onu_sn
                                write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                gpondel_finish, flow_result = self.del_gpononu(onu_sn, None)
                                if gpondel_finish == "failed":
                                    # 用户执行退出
                                    if flow_result == "logout":
                                        # 运行日志
                                        logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，用户执行OLT退出" % onu_sn
                                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                        # 计费发起的注册ONT
                                        if onu_sn_redis:
                                            # 计费触发注册ONU标识删除
                                            self.onu_set.discard(onu_sn_redis)
                                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                                "failed-logout", 10)  # id + sn码
                                        break
                                    elif flow_result == "result is None":
                                        # 运行日志
                                        logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，命令返回结果为空" % onu_sn
                                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                        # 计费发起的注册ONT
                                        if onu_sn_redis:
                                            # 计费触发注册ONU标识删除
                                            self.onu_set.discard(onu_sn_redis)
                                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                                "failed-result is None", 10)  # id + sn码
                                        # 运行日志
                                        logmsg = "失败: 序列码已经存在 删除失败 ONT SN:%s  结束" % onu_sn
                                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                else:
                                    time.sleep(1)
                                    # 保存 计费需要注册的ONT sn码  continue 以后能继续注册
                                    if onu_sn_redis:
                                        self.onu_set.add(onu_sn_redis)
                                    # 运行日志
                                    logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  结束" % onu_sn
                                    write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                                # 删除GPON成功 ,返回重新注册
                                continue
                            elif "获取ONT号失败" in flow_result:
                                write_log(data=flow_result, ip=self.tnip, port=self.tnport,
                                          level="error")
                                msg = "%s : %s 获取ONT号失败" % (olt_name, onu_sn)
                                redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                                if redis_result is None:
                                    sendTeam(msg, 'robot')
                                    redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            elif "端口下ONT已经达到最大数目" in flow_result:
                                write_log(data=flow_result, ip=self.tnip, port=self.tnport,
                                          level="error")
                                msg = "%s \n%s" % (olt_name, flow_result)
                                redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                                if redis_result is None:
                                    sendTeam(msg, 'robot')
                                    redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            else:
                                write_log(data=flow_result, ip=self.tnip, port=self.tnport,
                                          level="error")
                                failedcause = ""
                                for i in flow_result:
                                    if "失败" in i:
                                        failedcause = i
                                if failedcause == "":
                                    failedcause = flow_result
                                msg = "%s \nSN:%s 注册失败 \n%s" % (olt_name, onu_sn, failedcause)
                                # 发送微信
                                redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                                if redis_result is None:
                                    sendTeam(msg, 'robot')
                                    redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)

                            # 计费发起的注册ONT
                            if onu_sn_redis:
                                # 计费触发注册ONU标识删除
                                self.onu_set.discard(onu_sn_redis)
                                redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis), "onu login failed",
                                                    10)  # id + sn码

                            time.sleep(2)
                            continue

                        else:
                            ontid = flow_result
                            # 发送注册成功消息
                            a = slotid.replace('\r', '')
                            b = board_port.replace('\r', '')
                            c = ontid.replace('\r', '')
                            msg = f"设备名称：【{self.oltObj.olt_name}】\n\n" \
                                  f"机框位置:【{a}】槽【{b}】口【{c}】序\n" \
                                  f"SN：【{onu_sn}】\n" \
                                  f"VLAN信息：【{business_outer}/{business_intimal}】\n\n" \
                                  f"设备注册成功！！"
                            Save_OntRecord(self.olt_id, olt_name, "未配置小区名称", "华为GPON", "注册", 0, slotid, board_port,
                                           ontid, onu_sn, line_template, business_template, business_outer,
                                           business_intimal, gemport)
                            OnuAutoFindInfo.objects.create(olt_id=self.olt_id, olt_name=olt_name, find_time=find_time,
                                                           sn=onu_sn, register_status=0,
                                                           frame=frameid + '/' + slotid + '/' + board_port)
                            CheckSnMac.objects.create(vlan=business_outer, sn=onu_sn.strip(),
                                                      frame_info=frameid + '/' + slotid + '/' + board_port,
                                                      ont_id=ontid)
                            self.sendSuccessMessage(slotid, board_port, ontid, onu_sn, business_outer, business_intimal)
                            print("GPON注册流程耗时", time.time() - time_start)
                            # 运行日志
                            #
                            write_log(data=msg, ip=self.tnip, port=self.tnport)
                            # 将sn码 保存至配置文件中，供计费调取使用
                            file_path = os.path.join(LOG_DIR, "%s_%s" % (self.tnip, self.tnport))
                            if not os.path.exists(file_path):
                                os.makedirs(file_path, mode=0o777, exist_ok=True)
                            filename = os.path.join(file_path, "%s_%s_config.txt" % (self.tnip, self.tnport))
                            with open(filename, "a") as f:
                                f.write("\n")
                                f.write(
                                    'ont add {} {} sn-auth "{}" omci ont-lineprofile-id {} '.format(board_port,
                                                                                                    ontid,
                                                                                                    onu_sn,
                                                                                                    line_template))
                                f.write("\n")

                            # 计费发起的注册ONT
                            if onu_sn_redis:
                                # 计费触发注册ONU标识删除
                                self.onu_set.discard(onu_sn_redis)
                                redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                    "onu login succeed-%s槽%s口%s序" % (slotid, board_port, ontid),
                                                    10)  # id + sn码
                                # return  True , msg
                    # EPON 注册
                    elif len(onu_sn) == 14:
                        logmsg = "进入EPON注册流程 开始"
                        print(logmsg)
                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                        eponlogin_finish, flow_result = self.epon_flow(frameid=frameid,
                                                                       slotid=slotid,
                                                                       board_port=board_port,
                                                                       onu_mac=onu_sn,
                                                                       find_time=find_time,
                                                                       line_template_EPON=line_template,
                                                                       business_template_EPON=business_template,
                                                                       business_intimal=business_intimal,
                                                                       business_outer=business_outer,
                                                                       gemport=gemport)
                        logmsg = "进入EPON注册流程 结束"
                        print(logmsg)
                        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
                        if not eponlogin_finish:
                            if flow_result == "正在保存数据":
                                time.sleep(5)
                            # 用户执行退出
                            elif flow_result == "logout":
                                # 计费发起的注册ONT
                                if onu_sn_redis:
                                    # 计费触发注册ONU标识删除
                                    self.onu_set.discard(onu_sn_redis)
                                    redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                        "failed-logout", 10)
                                break

                            elif flow_result == "失败: MAC地址已存在":
                                # 运行日志
                                logmsg = "失败: MAC地址已存在 删除 ONT SN:%s  开始" % onu_sn
                                write_log(logmsg, self.tnip, self.tnport)
                                epondel_finish, flow_result = self.del_epononu(onu_mac=onu_sn, wechat_group=None)
                                if epondel_finish == "failed":
                                    # 用户执行退出
                                    if flow_result == "logout":
                                        # 运行日志
                                        logmsg = "失败: MAC地址已存在 删除 ONT SN:%s  删除过程中，用户执行OLT退出" % onu_sn
                                        write_log(logmsg, self.tnip, self.tnport)
                                        # 计费发起的注册ONT
                                        if onu_sn_redis:
                                            # 计费触发注册ONU标识删除
                                            self.onu_set.discard(onu_sn_redis)
                                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                                "failed-logout", 10)
                                        break

                                    elif flow_result == "result is None":
                                        # 运行日志
                                        logmsg = "失败: 序列码已经存在 删除 ONT SN:%s  删除过程中，命令返回结果为空" % onu_sn
                                        #
                                        write_log(logmsg, self.tnip, self.tnport)
                                        # 计费发起的注册ONT
                                        if onu_sn_redis:
                                            # 计费触发注册ONU标识删除
                                            self.onu_set.discard(onu_sn_redis)
                                            redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                                "failed-result is None", 10)  # id + sn码

                                    logmsg = "失败: MAC地址已存在 删除失败 ONT SN:%s  结束" % onu_sn
                                    write_log(logmsg, self.tnip, self.tnport)
                                else:
                                    time.sleep(1)
                                    # 保存 计费需要注册的ONT sn码  continue 以后能继续注册
                                    if onu_sn_redis:
                                        self.onu_set.add(onu_sn_redis)
                                    # 运行日志
                                    logmsg = "失败: MAC地址已存在 删除 ONT SN:%s  结束" % onu_sn
                                write_log(logmsg, self.tnip, self.tnport)
                                # 删除EPON成功 ,返回重新注册
                                continue

                            elif "获取ONT号失败" in flow_result:
                                write_log(logmsg, self.tnip, self.tnport, None, "error")
                                # 发送微信
                                msg = "%s : %s 获取ONT号失败" % (olt_name, onu_sn)
                                redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                                if redis_result is None:
                                    sendTeam(msg, 'robot')
                                    redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                                # msgsend_wechat(msg=msg, wechat_group=CASE_GROUP_NAME)
                            elif "已经达到最大数目" in flow_result:
                                write_log(logmsg, self.tnip, self.tnport, None, "error")
                                # 发送微信
                                msg = "%s \n%s" % (olt_name, flow_result)
                                redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                                if redis_result is None:
                                    sendTeam(msg, 'robot')
                                    redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)

                            else:
                                write_log(logmsg, self.tnip, self.tnport, None, "error")
                                failedcause = ""
                                for i in flow_result:
                                    if "失败" in i:
                                        failedcause = i
                                if failedcause == "":
                                    failedcause = flow_result
                                msg = "%s \nSN:%s注册失败 \n%s" % (olt_name, onu_sn, failedcause)
                                # 发送微信
                                redis_result = redis_oper.redis_get("register_failed_%s" % onu_sn)
                                if redis_result is None:
                                    sendTeam(msg, 'robot')
                                    redis_oper.conn.set("register_failed_%s" % onu_sn, onu_sn, ex=60 * 60 * 2)
                            # 计费发起的注册ONT
                            if onu_sn_redis:
                                # 计费触发注册ONU标识删除
                                self.onu_set.discard(onu_sn_redis)
                                redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis), "onu login failed",
                                                    10)  # id + sn码

                            time.sleep(1)
                            continue

                        else:
                            ontid = flow_result
                            # 注册ONT信息保存mysql
                            Save_OntRecord(self.olt_id, olt_name, "未配置小区名称", "华为EPON",
                                           "注册", 0, slotid, board_port, ontid, onu_sn, line_template,
                                           business_template, business_outer, business_intimal, gemport,
                                           )
                            OnuAutoFindInfo.objects.create(olt_id=self.olt_id, olt_name=olt_name, find_time=find_time,
                                                           sn=onu_sn, register_status=0,
                                                           frame=frameid + '/' + slotid + '/' + board_port)
                            CheckSnMac.objects.create(vlan=business_outer, sn=onu_sn.strip(),
                                                      frame_info=frameid + '/' + slotid + '/' + board_port,
                                                      ont_id=ontid)
                            self.sendSuccessMessage(slotid, board_port, ontid, onu_sn, business_outer, business_intimal)
                            print("EPON注册流程耗时", time.time() - time_start)

                            # 将sn码 保存至配置文件中，供计费调取使用
                            file_path = os.path.join(LOG_DIR, "%s_%s" % (self.tnip, self.tnport))
                            if not os.path.exists(file_path):
                                os.makedirs(file_path, mode=0o777, exist_ok=True)
                            filename = os.path.join(file_path, "%s_%s_config.txt" % (self.tnip, self.tnport))
                            with open(filename, "a") as f:
                                f.write("\n")
                                f.write(
                                    'ont add {} {} mac-auth "{}" oam ont-lineprofile-id {} '.format(board_port,
                                                                                                    ontid,
                                                                                                    onu_sn,
                                                                                                    line_template))
                                f.write("\n")

                            # 计费发起的注册ONT
                            if onu_sn_redis:
                                # 计费触发注册ONU标识删除
                                self.onu_set.discard(onu_sn_redis)
                                redis_oper.conn.set("%s_%s" % (self.olt_id, onu_sn_redis),
                                                    "onu login succeed-%s槽%s口%s序" % (slotid, board_port, ontid),
                                                    10)  # id + sn码
                                # return  True , msg
                else:
                    # 用户执行退出
                    if self.result == "logout":
                        break

                    # 未知情况
                    msg = "%s  \n命令:%s \n返回信息:%s\n返回信息类型 %s\n长度 %s)" % (
                        self.oltObj.olt_name, command, self.result, type(self.result), len(self.result))
                    write_log(msg, self.tnip, self.tnport, None, "error")
                    # 连接异常
                    if self.result == "":
                        return "exception"

            time.sleep(2)

    # 获取返回结果
    def commandResult_fun(self, command, read_mode=None, userrole=None, savelog=None):
        # from apps.olt import models
        # close_old_connections()
        """
               userrole : debugging  调试模式
               userrole : user       用户操作
               read_mode : int   获取所有返回数据  等待时间
               savelog :  是否将信息保存至日志文件中
        """
        test = 'my command==>:' + command
        write_log(test, self.tnip, self.tnport)
        if userrole is None:
            run_state = redis_oper.redis_get("%s_%s_runstate" % (self.tnip, self.tnport))
            if run_state == "false":
                # 静音模式退出
                # self.logout_host(silent_mode = True)
                return "logout"

        self.result = ""
        try:
            self.result = self.tn.read_very_eager().decode('GBK', errors='ignore')
            if self.result:
                logmsg = "之前残留的回执信息- %s" % self.result
                # 运行日志
                write_log(logmsg, self.tnip, self.tnport)
            print("command", command)
            self.tn.write(command.encode('ascii') + b'\n')
            if read_mode:
                time.sleep(int(read_mode))
                self.result = self.tn.read_very_eager().decode('GBK', errors='ignore')

            else:
                self.result = self.tn.read_until(")#".encode('ascii'), timeout=60).decode('GBK', errors='ignore')
            # print("resultresult",result)
            if "数据保存" in self.result:
                time.sleep(8)
                self.result += self.tn.read_very_eager().decode('GBK', errors='ignore')

            print("*" * 100)
            if self.result == "":
                print("result ==''")

            # 系统运行telnetobj 且 命令有返回结果
            if self.result and userrole is None:
                print("更新%s %s运行状态" % (self.tnip, self.tnport))
                redis_oper.conn.set("%s_%s_running" % (self.tnip, self.tnport), self.olt_id, 10)

            if "失败: 不存在自动发现的ONT" not in self.result:
                # 运行日志
                write_log(self.result, self.tnip, self.tnport, userrole)
            # print("执行命令返回结果", self.result)
            print("获取命令结果执行完事")

            # 用户进行查询操作的返回结果，不存入redis
            if userrole == "user":
                return self.result
            # 打开websocket连接， 将结果保存至redis。
            else:
                echo_resutl = redis_oper.redis_get("%s_%s_echo" % (self.tnip, self.tnport))
                if echo_resutl == "true":
                    redis_oper.conn.lpush("%s_%s_echo_result" % (self.tnip, self.tnport), self.result)
                    redis_oper.conn.lpush("%s_%s_echo_result" % (self.tnip, self.tnport), str(datetime.now())[:19])
                return self.result

        except Exception as e:
            print("execute_command-->", e)
            # redis 记录字段，异常断开连接
            redis_key = "%s_exception_connect" % self.olt_id
            redis_oper.conn.set(redis_key, "true")
            # 运行日志 和 错误日志
            write_log(traceback.format_exc(), self.tnip, self.tnport, userrole, 'error')
            return None

    def filter_foreign_onu(self, onu_info_list):
        sn_list = [i[1] for i in onu_info_list]
        filter_sn_list = []
        for j in sn_list:
            try:
                dev = OmpDevice.objects.get(device_code=j)
                if dev.equipment_status == 0:
                    filter_sn_list.append(j)
            except Exception as e:
                print(e)
                device = OmpDevice.objects.create()
                device.device_code = j
                device.device_type = 1
                device.import_time = datetime.now()
                device.device_status = 0
                device.device_usage = 0
                device.receiver = '系统处理'
                device.org_id = 1
                device.equipment_status = 0
                device.save()
                msg = """[{}]存在未校验光猫:[{}] \n\n请联系相关人员校验后使用！\n""".format(self.oltObj.olt_name, j)
                sendTeam(msg, 'robot')
                filter_sn_list.append(j)
        return [i for i in onu_info_list if i[1] not in filter_sn_list]

    def filter_onu(self, olt_id, onu_info_list, batchmigrate=None):
        """
        batchmigrate 计费发起的ONT批量迁移字段。计费专用
        """
        close_old_connections()
        # 已经设置 端口过滤 的端口
        if batchmigrate:
            board_info_list = list(
                BoardInfo.objects.filter(olt_info_id=olt_id, board_port__isnull=False, filtration="true").values(
                    "frameid", "slotid", "board_port"))
        else:
            # 已经设置 端口过滤 和 半自动注册 的端口
            board_info_list = list(
                BoardInfo.objects.filter(Q(filtration="true") | Q(run_mode="semi-automatic"), olt_info_id=olt_id,
                                         board_port__isnull=False).values("frameid", "slotid", "board_port"))
        # 黑名单中的SN码
        sn_blacklist = list(SnBlacklist.objects.filter(olt_info_id=olt_id).values_list("sn", flat=True))
        # 运行日志
        if sn_blacklist:
            logmsg = "黑名单SN：%s，olt_id:%s" % (",".join(sn_blacklist), olt_id)
            print(logmsg)
        else:
            logmsg = "黑名单SN：无，olt_id:%s" % olt_id
            print(logmsg)
        # 判断是否在黑名单中
        logmsg = "拉黑之前的 %s" % onu_info_list
        # print(logmsg)
        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
        for i in onu_info_list[::-1]:
            if i[1] in sn_blacklist:
                onu_info_list.remove(i)
        logmsg = "拉黑之后的 %s" % onu_info_list
        write_log(data=logmsg, ip=self.tnip, port=self.tnport)
        # print(logmsg)

        if board_info_list:
            for info in board_info_list:
                for i in onu_info_list[::-1]:
                    # print("%s %s"%(self.tnip, i))
                    i_list = list(i)
                    location_list = i_list[0].split("/")
                    frameid = location_list[0]  # 框
                    slotid = location_list[1]  # 槽
                    board_port = location_list[2]  # 板口
                    if info["frameid"] == int(frameid) and info["slotid"] == int(slotid) and info["board_port"] == int(
                            board_port):
                        onu_info_list.remove(i)
                        continue

        if onu_info_list:
            # 随机获取列表下标
            subscript = random.randrange(0, len(onu_info_list))

            location_list = onu_info_list[subscript][0].split("/")
            frameid = location_list[0]  # 框
            slotid = location_list[1]  # 槽
            board_port = location_list[2]  # 板口
            # EPON
            if "-" in onu_info_list[subscript][1][:16]:
                onu_num = onu_info_list[subscript][1][:14]
            # GPON
            else:
                onu_num = onu_info_list[subscript][1][:16]
        else:
            frameid = None
            slotid = None
            board_port = None
            onu_num = None
        return frameid, slotid, board_port, onu_num

    def get_sn_info(self, onu_sn, onu_type, wechat_group=None, userrole=None):
        close_old_connections()
        # 运行日志
        logmsg = "获取 %s ONT SN:%s 原始位置  流程开始" % (onu_type, onu_sn)
        write_log(logmsg, self.tnip, self.tnport)
        if onu_type == "GPON":
            # GPON 获取sn码命令
            command = "display ont info by-sn {}".format(onu_sn)
        else:
            # EPON 获取mac地址命令
            command = "display ont info by-mac {}".format(onu_sn)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        write_log(self.result, self.tnip, self.tnport)
        olt_obj = OltInfo.objects.get(olt_id=self.olt_id)

        # 异常情况
        if self.result is None:
            return "failed", False, False, False
        # 不支持by-sn  by-mac 方式查询ONT信息
        elif "参数错误，错误位于'^'所指的位置" in self.result:
            self.result = self.all_ontinfo()
            result = re.findall(r'.*? {} '.format(onu_sn), self.result)[0]
            result = [i for i in result.split(' ') if i != '']
            if result.__len__() <= 2:
                self.result = re.findall(r"(框/槽/端口: .*)|(.*? {} )".format(onu_sn), self.result)
                for index, val in enumerate(self.result):
                    val = val[1]
                    if onu_sn in val:
                        indexof = index
                ontid = int([i for i in self.result[indexof][1].split(' ') if i != ''][0])
                frame = self.result[indexof - 1][0].split(':')[1].strip()
                frameid, slotid, board_port = frame.split('/')[0], frame.split('/')[1], frame.split('/')[2]
                return frameid, slotid, board_port, ontid
            if onu_type == "GPON":
                if result.__len__() == 3:
                    frameid, slotid, board_port, ontid = result[0].split("/")[0], result[0].split("/")[1], \
                                                         result[0].split("/")[2], result[1]
                else:

                    frameid, slotid, board_port, ontid = result[0].split("/")[0], result[1].split("/")[0], \
                                                         result[1].split("/")[1], result[2]
            else:
                frameid, slotid, board_port, ontid = result[0].split("/")[0], result[0].split("/")[1], \
                                                     result[0].split("/")[2], result[1]
            return frameid, slotid, board_port, ontid
            # 用户主动退出
        elif self.result == "logout":
            return "logout", False, False, False
        else:
            if "框/槽/端口" in self.result:
                self.re_result = re.findall("框/槽/端口 .*?: (.*?)\r\n.*?ONT编号 .*?: (.*?)\r\n", self.result)
                print("获取ONT的原位置返回信息：", self.result)
                if self.re_result is None:
                    # print("get sn fail:%s  \n  %s"%(command,self.result))
                    logmsg = "%s: None正则获取ONT(%s)原位置:%s -->返回信息 %s" % (
                        olt_obj.olt_name, onu_sn, self.re_result, self.result)
                    print(logmsg)
                    # 运行日志 和 错误日志
                    write_log(logmsg, self.tnip, self.tnport, None, 'error')
                    # 发送微信
                    # msgsend_wechat(msg=logmsg, wechat_group=olt_obj.abnormal_group)
                    sendTeam(logmsg, 'robot')

                if not self.re_result:
                    # print("get sn fail:%s  \n  %s"%(command,self.result))
                    logmsg = "%s: []正则获取ONT(%s)原位置:%s -->返回信息 %s" % (
                        olt_obj.olt_name, onu_sn, self.re_result, self.result)
                    print(logmsg)
                    # 运行日志 和 错误日志
                    write_log(logmsg, self.tnip, self.tnport, None, 'error')
                    # 发送微信
                    # msgsend_wechat(msg=logmsg, wechat_group=olt_obj.abnormal_group)
                    sendTeam(logmsg, 'robot')

                print("self.re_result-->", self.re_result)
                location = self.re_result[0][0].split("/")

                # 运行日志
                logmsg = "获取 %s ONT SN:%s 原始位置  流程结束 （框:%s，槽:%s，端口:%s，ONT编号:%s）" % (
                    onu_type, onu_sn, location[0], location[1], location[2], self.re_result[0][1])
                write_log(logmsg, self.tnip, self.tnport)
                return location[0], location[1], location[2], self.re_result[0][1]  # 框 槽 口 ont编号
            # 没有得到ONT位置信息
            else:
                return self.result.splitlines()[1], False, False, False

    def del_gpononu(self, onu_sn, wechat_group=None, frameid=None, slotid=None, board_port=None, ontid=None,
                    userrole=None):
        close_old_connections()
        # 通过sn码删除ONU 先获取ONU位置和编号
        if not all([frameid, slotid, board_port, ontid]):
            frameid, slotid, board_port, ontid = self.getOntInfoBySn(onu_sn, "GPON")
            if frameid is None and slotid is None and board_port is None and ontid is None:
                frameid, slotid, board_port, ontid = self.get_sn_info(onu_sn, "GPON", wechat_group)

        # 异常情况
        if frameid == "result is None":
            return "failed", "result is None"

        # 用户主动退出
        if frameid == "logout":
            return "failed", "logout"
        # 查询虚拟端口号下的索引
        # display service-port port  0 / 2 / 0 ont 0
        command = 'display service-port port {}/{}/{} ont {}\n'.format(frameid, slotid, board_port, ontid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        # 异常情况
        if self.result is None:
            return "failed", "result is None"

        elif "面向交换业务流列表" in self.result:
            print("index_result-->: %s" % self.result)
            re_reslut = re.findall(" *([0-9].*?)gpon ", self.result)
            for i in re_reslut:
                command = "undo service-port %s" % i.split(" ")[0]
                self.commandResult_fun(command=command, userrole=userrole)

        elif "失败: 没有业务虚端口可以操作" in self.result:
            pass
        # 用户主动退出
        elif self.result == "logout":
            return "failed", "logout"
        else:
            # 运行日志 和 错误日志
            logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, command, self.result)
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            # msgsend_wechat(msg=logmsg, wechat_group=olt_obj.abnormal_group)
            sendTeam(logmsg, 'robot')

            return "failed", self.result

        interface_command = "interface gpon {}/{}".format(frameid, slotid)
        self.result = self.commandResult_fun(command=interface_command, userrole=userrole)

        # 异常情况
        if self.result is None:
            return "failed", "result is None"

        elif "失败: 单板类型错误" in self.result:
            print("del_onu GPON板卡类型错误：%s" % self.result)
            logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')

            return "failed", self.result
        elif "失败: 该板不存在" in self.result:
            print("del_onu GPON该板不存在，进入失败:%s" % self.result)
            logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')

            return "failed", self.result
        else:
            result_length = self.result.splitlines()
            # print("result_length", result_length)
            # 异常情况
            if self.result is None:
                return "failed", "result is None"

            # 用户执行退出
            if result_length[0] == "logout":
                return "failed", result_length[0]

            if result_length[1] != "":
                print("GPONinterface命令的未知情况：%s" % self.result)
                # 运行日志 和 错误日志
                logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, interface_command, self.result)
                write_log(logmsg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(logmsg, 'robot')

                return "failed", self.result

            ontdel_command = 'ont delete {} {}'.format(board_port, ontid)
            self.result = self.commandResult_fun(command=ontdel_command, userrole=userrole)

            # 异常情况
            if self.result is None:
                return "failed", "result is None"
            # 用户主动退出
            elif self.result == "logout":
                result = "failed"
                cause = "logout"

            elif "可以被删除的ONT数目: 1, 成功数目: 1" in self.result:
                msg = """发现需要移机的光猫\n\n[{}]{}/{}/{}/{}序\n\nSN:{}
                \n\n移机成功,\n\n即将注册!\n\n""".format(self.oltObj.olt_name,
                                                 frameid, slotid,
                                                 board_port, ontid,
                                                 onu_sn)
                print(msg)
                # 删除ONT信息保存mysql
                print(111)
                Save_OntRecord(self.olt_id, self.oltObj.olt_name, None, "华为GPON", "删除",
                               0, slotid, board_port, ontid, onu_sn, None, None, None, None, None)
                sendTeam(msg, 'robot')
                result = "succeed"
                cause = False

            elif "失败: 该配置对象存在业务虚端口" in self.result:
                msg = "%s: 失败: 该配置对象存在业务虚端口： %s 返回信息--> %s" % (self.oltObj.olt_name, ontdel_command, self.result)
                print(msg)
                # 运行日志 和 错误日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')
                result = "failed"
                cause = self.result
            else:
                msg = "删除ONT出现异常：{} -> {}".format(command, self.result)
                print(msg)
                msg = "%s: 删除ONT出现异常： %s 返回信息--> %s" % (self.oltObj.olt_name, ontdel_command, self.result)
                # 运行日志 和 错误日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                # sendTeam(msg, 'robot')
                sendTeam(msg, 'robot')

                result = "failed"
                cause = self.result

            self.commandResult_fun(command="quit", userrole=userrole)

            return result, cause

    def del_epononu(self, onu_mac, wechat_group=None, frameid=None, slotid=None, board_port=None, ontid=None,
                    userrole=None):
        close_old_connections()
        # 通过sn码删除ONU 先获取ONU位置和编号
        if not all([frameid, slotid, board_port, ontid]):
            frameid, slotid, board_port, ontid = self.getOntInfoBySn(onu_mac, "EPON")
            if frameid is None and slotid is None and board_port is None and ontid is None:
                frameid, slotid, board_port, ontid = self.get_sn_info(onu_mac, "EPON", wechat_group)

        # 异常情况
        if frameid == "result is None":
            return "failed", "result is None"

        # 用户主动退出
        if frameid == "logout":
            return "failed", "logout"

        # olt_obj = OltInfo.objects.get(olt_ip=self.tnip, olt_port=self.tnport)

        # 查询虚拟端口号下的索引
        command = 'display service-port port {}/{}/{} ont {}\n'.format(frameid, slotid, board_port, ontid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        print("command  self.result", self.result)

        # 异常情况
        if self.result is None:
            return "failed", "result is None"
        # 用户主动退出
        elif self.result == "logout":
            return "failed", "logout"

        elif "错误位于'^'所指的位置" in self.result:
            delEPON_command1 = 'undo service-port epon  {}/{}/{} ont {}\ny'.format(frameid, slotid, board_port, ontid)
            self.result = self.commandResult_fun(command=delEPON_command1, userrole=userrole)
            print("command_result删除EPON--->", self.result)
        else:
            if "面向交换业务流列表" in self.result:
                print("index_result-->:", self.result)
                re_reslut = re.findall(" *([0-9].*?)epon ", self.result)
                for i in re_reslut:
                    command = "undo service-port %s" % i.split(" ")[0]
                    self.commandResult_fun(command=command, userrole=userrole)
            elif "失败: 没有业务虚端口可以操作" in self.result:
                pass
            else:
                logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, command, self.result)
                # 运行日志 和 错误日志
                write_log(logmsg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(logmsg, 'robot')
                return "failed", self.result

        interface_command = "interface epon {}/{}".format(frameid, slotid)
        self.result = self.commandResult_fun(command=interface_command, userrole=userrole)

        # 异常情况
        if self.result is None:
            return "failed", "result is None"

        elif "失败: 单板类型错误" in self.result:
            logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            sendTeam(logmsg, 'robot')

            return "failed", self.result

        elif "失败: 该板不存在" in self.result:
            print("del_onu EPON该板不存在，进入失败:%s" % self.result)
            logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, interface_command, self.result)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            sendTeam(logmsg, 'robot')

            return "failed", self.result

        else:
            result_length = self.result.splitlines()
            print("result_length", result_length)
            # 异常情况
            if self.result is None:
                return "failed", "result is None"

            # 用户执行退出
            if result_length[0] == "logout":
                return "failed", result_length[0]

            if result_length[1] != "":
                print("EPONinterface命令的未知情况：%s" % self.result)
                # 运行日志 和 错误日志
                logmsg = "%s: %s 返回信息:%s" % (self.oltObj.olt_name, interface_command, self.result)
                write_log(logmsg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                # msgsend_wechat(msg=logmsg, wechat_group=olt_obj.abnormal_group)
                sendTeam(logmsg, 'robot')

                return "failed", self.result

            # ont delete 0 0
            ontdel_command = 'ont delete {} {}'.format(board_port, ontid)
            self.result = self.commandResult_fun(command=ontdel_command, userrole=userrole)
            # 异常情况
            if self.result is None:
                return "failed", "result is None"
            # 用户主动退出
            elif self.result == "logout":
                result = "failed"
                cause = "logout"

            elif "可以被删除的ONT数目: 1, 成功数目: 1" in self.result:

                msg = """发现需要移机的光猫\n\n[{}]{}/{}/{}/{}序\n\n
                MAC:{}\n\n移机成功,\n\n即将注册!\n\n""".format(self.oltObj.olt_name,
                                                       frameid, slotid, board_port, ontid, onu_mac)
                print(msg)
                Save_OntRecord(self.olt_id, self.oltObj.olt_name, None, "华为EPON", "删除",
                               0, slotid, board_port, ontid, onu_mac, None, None, None, None, None)
                # 运行日志
                print(2222)
                write_log(msg, self.tnip, self.tnport)
                sendTeam(msg, 'robot')
                result = "succeed"
                cause = False

            elif "失败: 该配置对象存在业务虚端口" in self.result:
                msg = "%s: 失败: 该配置对象存在业务虚端口： %s 返回信息--> %s" % (self.oltObj.olt_name,
                                                               ontdel_command, self.result)
                print(msg)
                # 运行日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')

                result = "failed"
                cause = self.result
            else:
                msg = "%s: 删除ONT出现异常： %s 返回信息--> %s" % (self.oltObj.olt_name, ontdel_command, self.result)
                print(msg)
                # 运行日志
                write_log(msg, self.tnip, self.tnport, None, 'error')
                # 发送微信
                sendTeam(msg, 'robot')

                result = "failed"
                cause = self.result

            self.commandResult_fun(command="quit", userrole=userrole)

            return result, cause

    def logout_host(self, exception=None, userrole=None, silent_mode=None):
        """
        return  exception = 异常退出
                userrole = user 用户登录，直接退出
        """
        """
        return  exception = 异常退出
                userrole = user 用户登录，直接退出
        """
        close_old_connections()

        if silent_mode:
            print("执行静音模式退出")
            self.tn.close()

        if userrole == "user":
            print("执行退出")
            while True:
                try:
                    self.tn.write(b"quit" + b'\n')
                    time.sleep(2)
                    quit_result = self.tn.read_very_eager().decode('GBK', errors='ignore')
                    if "退出登录" in quit_result or "Please save data before logout" in quit_result:
                        self.tn.write(b"y" + b'\n')
                        # 运行日志
                        write_log('OLT正常退出', self.tnip, self.tnport)
                        break
                except Exception as e:
                    # 运行日志 和 错误日志
                    write_log(e, self.tnip, self.tnport, None, 'error')
                    break
            self.tn.close()
        else:
            olt_info_obj = OltInfo.objects.get(olt_id=self.olt_id)
            up_down_remind = olt_info_obj.up_down_remind  # 上线、下线提醒

            # 异常断开连接
            if exception:
                olt_info_obj.host_status = '宕机'
                olt_info_obj.save()
                count = CheckTotalOltUser.objects.get(olt_ip=olt_info_obj.olt_ip).total_num
                msg = f"【{olt_info_obj.olt_name}】 异常登出！\n" \
                      f"时间：{str(datetime.now())[:19]}\n" \
                      f"IP：{olt_info_obj.olt_ip}\n" \
                      f"故障影响用户数量：{str(count)}\n" \
                      f"原因：设备异常断开连接"
                sendTeam(msg, 'robot')

            else:
                msg = "[{}]正常登出\n- 时间:{}\n- IP:{}\n人为操作退出！".format(olt_info_obj.olt_name, str(datetime.now())[:19],
                                                                   olt_info_obj.olt_ip)
                if up_down_remind == "是":
                    sendTeam(msg, 'robot')
                while True:
                    print("执行退出登录命令")
                    try:
                        self.tn.write(b"quit" + b'\n')
                        time.sleep(2)
                        quit_result = self.tn.read_very_eager().decode('GBK', errors='ignore')
                        if "退出登录" in quit_result or "Please save data before logout" in quit_result:
                            self.tn.write(b"y" + b'\n')
                            # 运行日志
                            write_log('OLT正常退出', self.tnip, self.tnport)
                            break
                    except Exception as e:
                        # 运行日志 和 错误日志
                        write_log(e, self.tnip, self.tnport, None, 'error')
                        break

                    # 人为操作  停止运行OLT 反馈字段
                    redis_oper.conn.set("%s_%s_stoprun_signal" % (self.tnip, self.tnport), 1, 10)
                print("退出里的删除唯一标识符")
                redis_oper.redis_del("%s_%s_run_uniqueid" % (self.tnip, self.tnport))
                redis_oper.redis_del("%s_%s_running" % (self.tnip, self.tnport))
            # 运行日志
            write_log(msg, self.tnip, self.tnport)
            print("执行退出,系统运行OLT，%s %s" % (self.tnip, self.tnport))

            self.tn.close()

    def gpon_flow(self, frameid, slotid, board_port, onu_sn, find_time, line_template_GPON, business_template_GPON,
                  business_intimal, business_outer, gemport):
        # olt_obj = OLT_Info.objects.get(id=self.olt_id)
        # 注册成功标识符
        gponlogin_finish = False
        # 开始注册 interface gpon 0/2
        command = 'interface gpon {}/{}'.format(frameid, slotid)
        self.result = self.commandResult_fun(command=command)
        # 异常情况
        if self.result is None:
            return gponlogin_finish, "result is None"

        elif "失败: 该板不存在" in self.result:
            print("GPON该板不存在，进入失败:%s" % self.result)
            return gponlogin_finish, "{}框/{}槽 \n Command:{} \n {}".format(frameid, slotid, command, self.result)
        elif "失败: 单板类型错误" in self.result:
            print("GPON板卡类型错误:%s" % self.result)
            return gponlogin_finish, "{}框/{}槽 \n Command:{} \n {}".format(frameid, slotid, command, self.result)
        elif "数据保存" in self.result or "数据正在保存" in self.result:
            time.sleep(1)
            # continue
            return gponlogin_finish, "正在保存数据"
        else:
            result_length = self.result.splitlines()
            print("result_length", result_length)
            if self.result is None:
                print("result == None")

            # 用户执行退出
            if result_length[0] == "logout":
                return gponlogin_finish, result_length[0]

            if result_length[1] != "":
                # logmsg = "%s 返回信息---> %s" % (command, self.result)
                #
                print("GPONinterface命令的未知情况：%s" % self.result)

                return gponlogin_finish, "{}框/{}槽 \n {}".format(frameid, slotid, self.result)
        ont_add = "ont add {} sn-auth {} omci\nont-lineprofile-id {} " \
                  "ont-srvprofile-id {}\ndesc {}".format(board_port,
                                                         onu_sn,
                                                         line_template_GPON,
                                                         business_template_GPON,
                                                         find_time[:10])
        self.result = self.commandResult_fun(command=ont_add)
        ontid = None
        if self.result is None:
            return gponlogin_finish, "result is None"

        elif "失败: 序列码已经存在" in self.result:
            self.commandResult_fun(command="quit")
            return gponlogin_finish, "失败: 序列码已经存在"

        elif "可以被添加的ONT数目" in self.result:
            # 获取ont id 号
            ontid_list = re.findall("ONT号 .*?:(.*)\r\n", self.result)
            if ontid_list is None:
                print("GPONget ontid fail:", self.result)
                result = self.result
                #
                self.commandResult_fun(command='quit')

                return gponlogin_finish, "获取ONT号失败\n {} \n 获取结果 {}".format(result, ontid_list)
            else:
                ontid = ontid_list[0]

        elif self.result == "logout":
            result_exit = self.result
            self.commandResult_fun(command='quit')
            return gponlogin_finish, result_exit
        elif "已经达到最大数目" in self.result:

            self.commandResult_fun(command='quit')
            return gponlogin_finish, "ONT({})注册失败：{}框/{}槽/{}端口下ONT已经达到最大数目".format(onu_sn, frameid, slotid, board_port)
        else:
            logmsg = self.result
            self.commandResult_fun(command='quit')
            return gponlogin_finish, "{}框/{}槽 \n command:{} \n  {}".format(frameid, slotid, ont_add, logmsg)

        # 读取eth端口信息
        eth_port = redis_oper.redis_get("%s_eth" % onu_sn)
        if eth_port:
            eth_port_list = eval(eth_port)
            print("eth_port", eth_port)
            print("eth_port", type(eth_port))
            print("eth_port_list", eth_port_list)
        else:
            eth_port_list = [1]

        for eth in eth_port_list:
            # ont port native-vlan 端口号 编号 eth 1 vlan 业务内层 priority 0
            ont_port_command = 'ont port native-vlan {} {} eth {} vlan {} priority 0'.format(board_port, ontid, eth,
                                                                                             business_intimal)  #
            self.result = self.commandResult_fun(command=ont_port_command)

            if self.result is None:
                return gponlogin_finish, "result is None"
            elif self.result == "logout":
                result_exit = self.result
                self.commandResult_fun(command='quit')
                return gponlogin_finish, result_exit
            elif "错误位于'^'所指的位置" in self.result:
                print("GPONerror-parameter", ont_port_command)
                logmsg = self.result
                self.commandResult_fun(command='quit')

                return gponlogin_finish, "{}框/{}槽 \n command:{}\n {}".format(frameid, slotid, ont_port_command, logmsg)
        # 添加报警模板
        alarm_profile_command = "ont optical-alarm-profile {} {} profile-id 3".format(board_port, ontid)
        self.commandResult_fun(command=alarm_profile_command)
        alarm_policy = "ont alarm-policy {} {} policy-id 1".format(board_port, ontid)
        self.commandResult_fun(command=alarm_policy)

        self.commandResult_fun(command='quit')
        # service-port vlan 业务外层 gpon 0/槽号/端口号 ont 编号 gemport 1 multi-service user-vlan 业务内层
        service_port = 'service-port vlan {} gpon {}/{}/{}\nont {} gemport {} multi-service user-vlan {}\n'.format(
            business_outer, frameid, slotid, board_port, ontid, gemport, business_intimal)  # 虚拟端口业务
        self.result = self.commandResult_fun(command=service_port)

        if self.result is None:
            return gponlogin_finish, "result is None"
        elif self.result == "logout":
            result_exit = self.result
            # self.commandResult_fun(command='quit')
            return gponlogin_finish, result_exit

        elif "错误位于'^'所指的位置" in self.result:
            logmsg = "GPON注册命令： %s 返回信息-- > %s " % (service_port, self.result)
            print(logmsg)
            #
            # 发送微信

            return gponlogin_finish, "{}框/{}槽 \n Command:{}\n  {}".format(frameid, slotid, service_port, logmsg)
        elif "失败" in self.result:
            logmsg = self.result
            print(logmsg)
            # 运行日志 和 错误日志
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 发送微信
            command = 'interface gpon {}/{}'.format(frameid, slotid)
            self.result = self.commandResult_fun(command=command)
            # ont delete 0 0
            ontdel_command = 'ont delete {} {}'.format(board_port, ontid)
            self.result = self.commandResult_fun(command=ontdel_command, userrole=None)

            if self.result is None:
                return gponlogin_finish, "result is None"
            # 用户主动退出
            elif self.result == "logout":
                return gponlogin_finish, self.result
            self.result = self.commandResult_fun(command="quit", userrole=None)
            # 用户主动退出
            if self.result == "logout":
                return gponlogin_finish, self.result
            return gponlogin_finish, "{}框/{}槽 \n Command:{}\n  {}".format(frameid, slotid, service_port, logmsg)
        gponlogin_finish = True
        return gponlogin_finish, ontid

    def epon_flow(self, frameid, slotid, board_port, onu_mac, find_time, line_template_EPON, business_template_EPON,
                  business_intimal, business_outer, gemport):
        # 注册成功标识符
        eponlogin_finish = False
        # 开始注册 interface epon 0/2
        command = 'interface epon {}/{}'.format(frameid, slotid)
        self.result = self.commandResult_fun(command=command)

        # 异常情况
        if self.result is None:
            return eponlogin_finish, "result is None"

        elif "失败: 该板不存在" in self.result:
            print("EPON该板不存在，进入失败:%s" % (self.result))

            return eponlogin_finish, "{}框/{}槽 \n command:{} \n {}".format(frameid, slotid, command, self.result)
        elif "失败: 单板类型错误" in self.result:
            print("EPON板卡类型错误:%s" % (self.result))

            return eponlogin_finish, "{}框/{}槽 \n command:{} \n {}".format(frameid, slotid, command, self.result)
        elif "数据保存" in self.result or "数据正在保存" in self.result:
            time.sleep(1)
            # continue
            return eponlogin_finish, "正在保存数据"
        else:
            result_length = self.result.splitlines()
            if self.result is None:
                print("result == None")

            # 用户执行退出
            if result_length[0] == "logout":
                return eponlogin_finish, result_length[0]

            if result_length[1] != "":
                return eponlogin_finish, "{}框/{}槽 \n {}".format(frameid, slotid, self.result)

        ont_add = "ont add {} mac-auth {} oam\nont-lineprofile-id {}\nont-srvprofile-id {}\ndesc {}".format(
            board_port, onu_mac, line_template_EPON, business_template_EPON, find_time[:10])

        self.result = self.commandResult_fun(command=ont_add)
        ontid = None
        if self.result is None:
            return eponlogin_finish, "result is None"

        elif "失败: MAC地址已存在" in self.result:
            self.commandResult_fun(command="quit")
            return eponlogin_finish, "失败: MAC地址已存在"

        elif "可以被添加的ONT数目" in self.result:
            # 获取ont id 号
            ontid_list = re.findall("ONT号 .*?:(.*)\r\n", self.result)
            print("获取ONTid处 正则后的ontid_list", ontid_list)
            if ontid_list is None:
                result = self.result
                self.commandResult_fun(command='quit')
                return eponlogin_finish, "获取ONT号失败\n {} \n 获取结果 {}".format(result, ontid_list)
            else:
                ontid = ontid_list[0]
        elif self.result == "logout":
            result_exit = self.result
            self.commandResult_fun(command='quit')
            return eponlogin_finish, result_exit
        elif "已经达到最大数目" in self.result:

            self.commandResult_fun(command='quit')
            return eponlogin_finish, "ONT({})注册失败：{}框/{}槽/{}端口下ONT已经达到最大数目".format(onu_mac, frameid, slotid, board_port)
        else:
            logmsg = self.result
            self.commandResult_fun(command='quit')
            return eponlogin_finish, "{}框/{}槽 \n command:{} \n  {}".format(frameid, slotid, ont_add, logmsg)
        ont_port_command = 'ont port native-vlan {} {} eth 1 vlan {}'.format(board_port, ontid, business_intimal)

        self.result = self.commandResult_fun(command=ont_port_command)

        # 异常情况
        if self.result is None:
            return eponlogin_finish, "result is None"
        elif self.result == "logout":
            result_exit = self.result
            self.commandResult_fun(command='quit')
            return eponlogin_finish, result_exit

        elif "错误位于'^'所指的位置" in self.result:
            print("EPONerror-parameter", ont_port_command)
            logmsg = self.result
            self.commandResult_fun(command='quit')
            return eponlogin_finish, "{}框/{}槽 \n command:{}\n {}".format(frameid, slotid, ont_port_command, logmsg)
        # 添加报警模板
        alarm_profile_command = "ont optical-alarm-profile {} {} profile-id 3".format(board_port, ontid)
        self.commandResult_fun(command=alarm_profile_command)
        alarm_policy = "ont alarm-policy {} {} policy-id 1".format(board_port, ontid)
        self.commandResult_fun(command=alarm_policy)

        self.commandResult_fun(command='quit')
        # service-port vlan 业务外层 gpon 0/槽号/端口号 ont 编号 gemport 1 multi-service user-vlan 业务内层
        service_port = 'service-port vlan {} epon {}/{}/{} ont {}\nmulti-service user-vlan {}\ntag-transform translate\n'.format(
            business_outer, frameid, slotid, board_port, ontid, business_intimal)  # 虚拟端口业务
        self.result = self.commandResult_fun(command=service_port)

        # 异常情况
        if self.result is None:
            return eponlogin_finish, "result is None"
        # 用户主动退出
        if self.result == "logout":
            result_exit = self.result
            # self.commandResult_fun(command='quit')
            return eponlogin_finish, result_exit

        elif "错误位于'^'所指的位置" in self.result:
            logmsg = "EPON注册命令： %s 返回信息-- > %s " % (service_port, self.result)
            print(logmsg)
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            return eponlogin_finish, "{}框/{}槽 \n command:{}\n  {}".format(frameid, slotid, service_port, logmsg)
        elif "失败" in self.result:
            logmsg = self.result
            print(logmsg)
            write_log(logmsg, self.tnip, self.tnport, None, 'error')
            # 失败以后删除 ONT
            command = 'interface epon {}/{}'.format(frameid, slotid)
            self.result = self.commandResult_fun(command=command)
            # 异常情况
            if self.result is None:
                return eponlogin_finish, "result is None"
            # 用户主动退出
            if self.result == "logout":
                return eponlogin_finish, self.result

            # ont delete 0 0
            ontdel_command = 'ont delete {} {}'.format(board_port, ontid)
            self.result = self.commandResult_fun(command=ontdel_command, userrole=None)
            # 异常情况
            if self.result is None:
                return eponlogin_finish, "result is None"
            # 用户主动退出
            if self.result == "logout":
                return eponlogin_finish, self.result

            self.result = self.commandResult_fun(command="quit", userrole=None)
            # 异常情况
            if self.result is None:
                return eponlogin_finish, "result is None"
            # 用户主动退出
            if self.result == "logout":
                return eponlogin_finish, self.result

            return eponlogin_finish, "{}框/{}槽 \n command:{}\n  {}".format(frameid, slotid, service_port, logmsg)
        gponlogin_finish = True
        return gponlogin_finish, ontid

    # 查看所有板卡
    def board_info(self, scope, userrole=None):
        """
        return scope = "usable"     业务板卡且状态正常的信息 [['6', 'H807GPBD', '正常']]
               scope = "all"        所有板卡的信息 [['5', 'H807GPBD', '待确认'], ['6', 'H807GPBD', '正常'], ['7', 'H801SCUN', '备用正常'],
                ['8', 'H801SCUN', '主用正常'], ['17', 'H801X2CS', '正常'], ['18', 'H801GICF', '正常']]
               scope = "num_list"   #业务板卡号
        """
        info_num = 1
        board_command = "display board 0"
        result = ""
        while True:
            self.result = self.commandResult_fun(command=board_command, userrole=userrole)
            # print("self.result----->",self.result)
            if self.result is None:
                return False, "返回结果为空，连接异常"
            if "槽位主控板的数据" in self.result:
                print("self.result", self.result)
                # print("保存数据中:第%s次"%info_num)
                time.sleep(5)
                info_num += 1
                result += self.result
                continue
            else:
                result = self.result
                break
        print(result)
        if "槽号  板名称     状态" in result:
            re_reslut = re.findall("(.*[0-9].*?)\r\n", self.result)
            board_info = []
            board_usable = []
            slot_list = []

            print("re_reslut --->", re_reslut)
            for i in re_reslut:
                if "在线状态" in i:
                    pass
                elif "display" in i:
                    pass
                else:
                    board_info.append([value for value in i.split(" ") if value != ""])

                if "GP" in i and "正常" in i:
                    board_usable.append([value for value in i.split(" ") if value != ""])
                if "EP" in i and "正常" in i:
                    board_usable.append([value for value in i.split(" ") if value != ""])
                if "GP" in i or "EP" in i:
                    slot_list.append([value for value in i.split(" ") if value != ""][0])
            # 返回所有单板信息
            if scope == "all":
                return board_info, result
            # 返回可用单板信息
            elif scope == "usable":
                return board_usable, False
            # 业务板卡号 列表
            elif scope == "num_list":
                # print("slot_list",slot_list)
                return slot_list, False
        else:
            print("display board 0 获取信息异常", result)
            # 运行日志 和 错误日志
            logmsg = "display board 0 获取信息异常: %s " % (result)
            write_log(logmsg, self.tnip, self.tnport)
            return False, result

        # 啥也没有 board_info[]

        # board_usable[['6', 'H807GPBD', '正常']]
        # print("board_usable", board_usable)

        # [['5', 'H807GPBD', '待确认'], ['6', 'H807GPBD', '正常'], ['7', 'H801SCUN', '备用正常'],
        # ['8', 'H801SCUN', '主用正常'], ['17', 'H801X2CS', '正常'], ['18', 'H801GICF', '正常']]
        # print("board_info", board_info)

    # 查看单板信息
    def board_one(self, board_num, scope, userrole=None):
        """
        return scope = "port_num"    返回板卡下端口数量列表[0,1,2,3,4,5,6,7]
               scope = "board_info"  返回板卡信息
               scope = "port_state"  返回板卡下端口状态
        """
        board_command = "display board 0/%s" % board_num
        self.result = self.commandResult_fun(command=board_command, userrole=userrole)
        if self.result:
            if scope == "port_num":
                # print("self.result",self.result)
                re_reslut = re.findall("端口([0-9].*)下,", self.result)
                port_num_list = []
                if re_reslut:
                    for i in re_reslut:
                        try:
                            port_num_list.append(i.split("/")[2])
                        except:
                            port_num_list.append(i)

                return port_num_list
            elif scope == "board_info":
                return self.result
            elif scope == "port_state":
                re_reslut = re.findall("板名称 .*: (.*?)  .*\r\n", self.result)
                boardPortInfo = []

                if re_reslut:
                    # print("1111----------->", re_reslut[0])
                    if "GP" in re_reslut[0]:
                        re_reslut = re.findall("([0-9].*  .*GPON.*?)\r\n", self.result)
                        # print("re_reslut", re_reslut)
                        boardPortInfo = []
                        if re_reslut:
                            for i in re_reslut:
                                boardPortInfo_dict = {}
                                i_list = i.split(" ")
                                boardPortInfo_dict["num"] = i_list[-0]
                                boardPortInfo_dict["portStatus"] = i_list[-1]
                                boardPortInfo.append(boardPortInfo_dict.copy())
                        return boardPortInfo
                    elif "EP" in re_reslut[0]:
                        re_reslut = re.findall("([0-9].)  .*EPON  .*\r\n", self.result)
                        if re_reslut:
                            for i in re_reslut:
                                boardPortInfo_dict = {}
                                boardPortInfo_dict["num"] = i.replace(" ", "")
                                boardPortInfo_dict["portStatus"] = "在位"
                                boardPortInfo.append(boardPortInfo_dict.copy())
                        return boardPortInfo
                else:
                    return False
        return False

    # 获取板卡下某个端口信息
    def get_boardport_info(self, olt_type, slotid, board_port, userrole=None):
        """
                display port state 0
        """
        board_command = "interface %s 0/%s" % (olt_type, slotid)
        self.result = self.commandResult_fun(command=board_command, userrole=userrole)

        if self.result is None:
            return

        if "不存在" in self.result or "类型错误" in self.result:
            return self.result
        board_command = "display port state %s" % (board_port)
        self.result = self.commandResult_fun(command=board_command, userrole=userrole)
        result = self.result
        board_command = "quit"
        self.result = self.commandResult_fun(command=board_command, userrole=userrole)
        # print("self.result",result)
        return result

    def ont_info(self, frameid, slotid=None, board_port=None, userrole=None, filtrate=None):
        """
        display ont info 0 7 2 all
        """
        command = "display ont info {}".format(frameid)
        if slotid:
            command += " %s" % slotid
        if board_port:
            command += " %s" % board_port
        command += " all"
        # 没有ONT可供查询
        # 失败: 该板不存在
        # 失败: 端口不存在
        # 失败: 该框不存在
        # 失败: 单板类型错误
        # 符合条件的ONT不存在
        self.result = self.commandResult_fun(command=command, userrole=userrole)

        # 是否需要处理返回的信息
        if filtrate == True:
            result_list = []
            if self.result is None:
                result_list = []
            elif "失败: 该板不存在" in self.result:
                result_list = "失败: 该板不存在"
            elif "失败: 端口不存在" in self.result:
                result_list = "失败: 端口不存在"
            elif "没有ONT可供查询" in self.result:
                result_list = "没有ONT可供查询"
            elif "符合条件的ONT不存在" in self.result:
                result_list = "符合条件的ONT不存在"
            elif "失败: 该框不存在" in self.result:
                result_list = "失败: 该框不存在"
            elif "失败: 单板类型错误" in self.result:
                result_list = "失败: 单板类型错误"
            else:
                re_reslut = re.findall("([0-9]/.*?线 .*)\r\n", self.result)
                for i in re_reslut:
                    result_list.append([j for j in i.split("  ") if j != ""])
            return result_list
        else:
            return self.result

    # 获取ONT详细信息
    def sn_ont_info(self, sn, get_content=None, userrole=None):
        """
                display ont info by-mac C070-094E-6B4E
                display ont info by-sn 5A544547C6B38F4A
                get_content="info"  获取框/槽/端口 编号 控制标志 运行标志 配置状态 匹配状态 信息
                get_content="state"  获取 详细信息  信息比较多
        """
        command = "display ont info "
        if len(sn) == 16 and "-" not in sn:
            command += " by-sn {}".format(sn[:16])

        if len(sn) == 14 and "-" in sn:
            command += " by-mac {}".format(sn)

        # 没有ONT可供查询
        # 符合条件的ONT不存在
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        # print("command", command)
        print("self.result   by-sn", self.result)

        result_list = []
        if self.result:
            if "没有ONT可供查询" in self.result:
                result_list = "没有ONT可供查询"
            elif "符合条件的ONT不存在" in self.result:
                result_list = "符合条件的ONT不存在"
            elif "错误位于'^'所指的位置" in self.result:
                result_list = "OLT不支持 %s 命令" % (command)
            else:
                if get_content == "info":
                    # ['0/ 6/4', ' 0', '485754432D674F29', '激活', '离线', '初始状态', '初始状态', '否'
                    re_reslut = re.findall(
                        "框/槽/端口 .*?: (.*?)\r\n.*?ONT编号 .*?: (.*?)\r\n.*?控制标志 .*?: (.*?)\r\n.*?运行标志 .*?: (.*?)\r\n.*?配置状态 .*?: (.*?)\r\n.*?匹配状态 .*?: (.*?)\r\n",
                        self.result)
                    result_list = list(re_reslut[0])
                    result_list.insert(2, sn)
                    result_list.append("")
                    result_list = [result_list]
                elif get_content == "state":
                    result_list = self.result.splitlines()[2:26]

        return result_list

    # 确认单板
    # board confirm {}/{}
    def confirm_slot(self, slotid, userrole=None):
        if len(slotid) > 1:
            confirm_command = "board confirm 0"
            self.result = self.commandResult_fun(command=confirm_command, userrole=userrole)

        elif len(slotid) == 1:
            confirm_command = "board confirm {}/{}".format(0, slotid[0]["num"])
            self.result = self.commandResult_fun(command=confirm_command, userrole=userrole)

        if self.result:
            return True, False
        else:
            return False, "连接异常"

    # 端口自动发现
    def port_autofind(self, board_type, slotid, port_num=None, userrole=None):
        if port_num is None:
            port_num = 16
        time22 = time.time()
        command = "interface {} {}/{}".format(board_type, 0, slotid)
        self.result = self.commandResult_fun(command=command, read_mode=4, userrole=userrole)
        print("time22", time.time() - time22)
        enable_auto_find = ""
        autofind_result = ""
        time11 = time.time()
        for i in range(port_num):
            enable_auto_find += "port {} ont-auto-find enable\n".format(i)
        self.result = self.commandResult_fun(command=enable_auto_find, userrole=userrole)
        # time.sleep(0.5)
        if self.result is None:
            return False, "连接异常"
        if "失败" in self.result:
            autofind_result = self.result
        enable_auto_find += "port 15 ont-auto-find enable"
        self.result = self.commandResult_fun(command=enable_auto_find, read_mode=10, userrole=userrole)
        print("开启端口发现 耗时：", time.time() - time11)
        time.sleep(1)
        command = "\n"
        self.commandResult_fun(command=command, read_mode=3, userrole=userrole)
        command = "quit"
        self.commandResult_fun(command=command, userrole=userrole)
        # command = "\n"
        # self.commandResult_fun(command=command, userrole=userrole)
        print("time33", time.time() - time22)
        return True, autofind_result

    # 用户调试模式 自定义输入命令
    def userinput_command(self, command, userrole=None):
        print("交互command", command)
        self.tn.write(command.encode('ascii') + b'\n')
        while True:
            time.sleep(2)
            userinput_result = self.tn.read_very_eager().decode('GBK', errors='ignore')
            print("交互模式信命令回执：", userinput_result)
            redis_oper.conn.lpush("%s_%s_%s_echo_resultdebugging" % (self.tnip, self.tnport, self.user_timestamp),
                                  userinput_result)

            if ")#" in userinput_result or "}:" in userinput_result:
                break
            elif userinput_result is None:
                break
            elif "任意键继续显示" in userinput_result:
                break

    # OLT持续运行时间
    def get_runtime(self, userrole=None):
        command = "display sysuptime"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    def get_oltcurrenttime(self, userrole=None):
        command = "display time\n"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # 获取上行板光衰
    def board_light_attenuation(self, board_num, board_type, userrole=None):
        command = "interface {} 0/{}".format(board_type, board_num)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        command = "display port ddm-info 0"
        result1 = self.commandResult_fun(command=command, userrole=userrole)
        command = "display port ddm-info 1"
        result2 = self.commandResult_fun(command=command, userrole=userrole)
        command = "quit"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return result1 + result2

    # 获取ONT光衰
    def ont_light_attenuation(self, ont_type, frameid, slotid, board_port, ontNum, userrole=None):
        """display ont optical-info 0 2
        失败: ONT不在线
        MA5600T(config-if-epon-0/7)# """

        command = "interface {} {}/{}".format(ont_type, frameid, slotid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        command = "display ont optical-info {} {}".format(board_port, ontNum)
        result1 = self.commandResult_fun(command=command, userrole=userrole)
        command = "quit"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return result1

    # 获取ONT 上线、下线记录 10条
    def ontlogin_log(self, ont_type, frameid, slotid, board_port, ontNum, userrole=None):
        """
        interface gpon 0/5
        display ont register-info 0 1
        quit
         ---------------------------------------------------------------------
         索引编号            : 10
         认证方式            : SN认证
         ONT序列号           : 48575443A843DA52
         密   码             :
         ONT逻辑标识         :
         校验码              :
         ONT类型             : 120C
         上线时间            : 2021-01-03 13:55:40+08:00
         下线时间            : -
         下线原因            : -
         ---------------------------------------------------------------------
        """

        command = "interface {} {}/{}".format(ont_type, frameid, slotid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        command = "display ont register-info {} {}".format(board_port, ontNum)
        result1 = self.commandResult_fun(command=command, userrole=userrole)
        command = "quit"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return result1

    # 告警事件
    def alarm_history(self, starttime, endtime, userrole=None):
        """
        display alarm history alarmtime start 2021-01-10 00:00:00 end 2021-01-19 23:00:00 detail

        """
        print("starttime", starttime)
        print("endtime", endtime)

        command = "display alarm history alarmtime start %s\nend %s detail\n" % (str(starttime), str(endtime))
        # command = "display alarm history alarmtime start 2021-01-13 00:00:00\nend 2021-01-21 23:59:59 detail\n"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # 单板温度
    def board_temperature(self, board, userrole=None):
        command = "display temperature 0/{}".format(board)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # 修改OLT系统时间
    def changge_systemtime(self, changetime, userrole=None):
        command = "time {}".format(changetime)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # OLT配置信息
    def olt_configinfo(self, userrole=None):
        command = "display current-configuration simple\n"
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        return self.result

    # 获取OLT所有的ONT信息
    def all_ontinfo(self, userrole=None):
        command = "scroll 512"
        self.commandResult_fun(command=command, userrole=userrole)
        self.tn.write("display ont info 0 all".encode('ascii') + b'\n')
        all_result = ""
        while True:
            time.sleep(random.randint(1, 5))
            result = self.tn.read_very_eager().decode('GBK', errors='ignore')
            if "任意键继续显示" in result:
                all_result += result
                all_result += "\n"
                self.tn.write(" ".encode('ascii') + b'\n')
            else:
                all_result += result
                break

        return all_result

    # 获取版口光衰
    def getBoardlight_attenuation(self, board_type, board, port):
        command = f'interface {board_type} 0/{board}'
        self.commandResult_fun(command)
        port_command = f'display port state {port}'
        result = self.commandResult_fun(port_command)
        result = result.splitlines()[2:8] + result.splitlines()[13:14] + result.splitlines()[17:18]
        self.commandResult_fun('quit')
        return result

    # 获取口子用户信息
    def getBoardOntInfo(self, board_type, board, port):
        command = f'interface {board_type} 0/{board}'
        self.commandResult_fun(command)
        command1 = f'display ont info {port} all '
        result = self.commandResult_fun(command1)
        if board_type == 'GPON':
            result = result[:result.find('在线:') + 10].splitlines()
        else:
            result = result.splitlines()
        self.commandResult_fun('quit')
        return result

    # up dowm 端口
    def changePortStatus(self, board_type, frameid, slotid, change, userrole=None):
        command = "interface {} {}/{}".format(board_type, frameid, slotid)
        self.result = self.commandResult_fun(command=command, userrole=userrole)
        try:
            self.commandResult_fun(command=change, userrole=userrole)
            command = "quit"
            self.commandResult_fun(command=command, userrole=userrole)
            status = True
        except:
            command = "quit"
            self.commandResult_fun(command=command, userrole=userrole)
            status = False
        return status

    def getOntInfoBySn(self, sn, ont_type):
        ontInfo = OntRecord.objects.filter(olt_id=self.oltObj.olt_id, olt_type="华为" + ont_type, sn__contains=sn,
                                           register_type="注册")
        if ontInfo.__len__() > 0:
            ontInfo = ontInfo.last()
            return ontInfo.frameid, ontInfo.slotid, ontInfo.board_port, ontInfo.ont_num
        else:
            return None, None, None, None

    def sendSuccessMessage(self, slotid: str, board: str, ontid: str, sn: str, outer: str, intimal: str):
        slotid = slotid.replace('\r', '')
        board = board.replace('\r', '')
        ontid = ontid.replace('\r', '')
        sn = sn.replace('\r', '')
        msg = "设备名称：【%s】\n\n" \
              "机框位置：%s槽%s口%s序\n" \
              "SN：【%s】\n" \
              "VLAN信息：%s/%s\n" \
              "装机时间：%s\n\n" \
              "设备注册成功!" % (self.oltObj.olt_name, slotid, board, ontid, sn, outer, intimal, str(datetime.now())[:19])
        # print(msg)
        sendTeam(msg, 'robot')
        return True

    # def delOnuAllByBoard(self, board_type, board, port):
    #     command = f"display ont info 0 {board} {port} all"
    #     result = self.commandResult_fun(command)
    #     content = self.getInfoByResult(result)
    #     for i in content:
    #         service_port_command = f"display service-port port {i[0]}/{i[1]}/{i[2]} ont {i[3]}"
    #         service_port_result = self.commandResult_fun(service_port_command)
    #         if "面向交换业务流列表" in service_port_result:
    #             print("index_result-->: %s" % self.result)
    #             re_reslut = re.findall(" *([0-9].*?)[ge]pon ", self.result)
    #             for j in re_reslut:
    #                 command = "undo service-port %s" % j.split(" ")[0]
    #                 self.commandResult_fun(command=command)
    #
    #         elif "失败: 没有业务虚端口可以操作" in service_port_result:
    #             pass
    #         interface_command = f"interface {board_type} {i[0]}/{i[1]}"
    #         self.commandResult_fun(interface_command)
    #         ontdel_command = f'ont delete {i[2]} {i[3]}'
    #         self.commandResult_fun(ontdel_command)
    #
    # def getInfoByResult(self, result: str):
    #     content = result.split("-" * 77)[2].splitlines()
    #     content = [i for i in content if i != ' ' and i != ''][:-1]
    #     source = list()
    #     for i in content:
    #         info_list = list()
    #         _ = re.findall("\d+", i)
    #         info_list.append(_[0])
    #         info_list.append(_[1])
    #         info_list.append(_[2])
    #         info_list.append(_[3])
    #         source.append(info_list)
    #     return source


def hwolt_run(tnip, tnport, username, password):
    # OLT运行唯一标识符
    unique_identifier = redis_oper.redis_get("%s_%s_run_uniqueid" % (tnip, tnport))
    if unique_identifier is None:
        close_old_connections()
        obj = OltInfo.objects.get(olt_ip=tnip, olt_port=tnport)
        redis_oper.conn.set("%s_%s_run_uniqueid" % (tnip, tnport), "%s" % obj.id)

    while True:
        print("创建telnet连接")
        telnet_client = telnetip(tnip, tnport, username, password)
        # 代表OLT已经启动 ，但是 是否启动成功 不一定
        redis_oper.conn.set("%s_%s_runstate" % (tnip, tnport), "true")
        print("登录OLT逻辑运行 开始")
        result, msg = telnet_client.login_host()
        print("登录OLT逻辑运行 完毕")
        print("result,msg", result, msg)
        # 登录成功
        if result:
            result = telnet_client.base_config(1)
            if result:
                exit_result = telnet_client.onu_login()
                print("不注册了要退出", exit_result)
                # 运行日志
                logmsg = "%s:%s -->telnet_client.onu_login执行完毕，即将执行logout_host" % (tnip, tnport)
                write_log(logmsg, tnip, tnport)
                # 意外断开连接
                if exit_result == "exception":
                    # redis 记录字段，异常断开连接
                    redis_key = "%s_exception_connect" % telnet_client.olt_id
                    redis_oper.conn.set(redis_key, "true")

                    telnet_client.logout_host(exception=exit_result)
                    continue
                # 静音退出
                elif exit_result == "silent_mode":
                    telnet_client.logout_host(silent_mode=exit_result)
                    break

                # 正常退出
                else:
                    telnet_client.logout_host()
                    break

            else:
                # 运行日志 和 错误日志
                logmsg = "登录%s:%s 基本配置失败" % (tnip, tnport)
                print(logmsg)
                redis_oper.redis_del("%s_%s_run_uniqueid" % (tnip, tnport))
                write_log(logmsg, tnip, tnport, None, 'error')
                break
        # 登录失败
        else:
            # 长时间断开连接，恢复后会报错
            if msg == "Connection reset by peer":
                continue
            else:
                # 运行日志 和 错误日志
                print("login failed！{}:{}".format(tnip, tnport))
                write_log(msg, tnip, tnport, None, 'error')
                redis_oper.conn.delete("%s_%s_run_uniqueid" % (tnip, tnport))
                break
